package com.moyu.plugins.pokemsg.Listener;

import catserver.api.bukkit.event.ForgeEvent;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.ListenerOptions;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.injector.GamePhase;
import com.moyu.plugins.pokemsg.PokeMsg;
import com.pixelmonmod.pixelmon.api.events.CaptureEvent.SuccessfulCapture;
import com.pixelmonmod.pixelmon.api.events.spawning.LegendarySpawnEvent;
import com.pixelmonmod.pixelmon.api.events.spawning.LegendarySpawnEvent.DoSpawn;
import com.pixelmonmod.pixelmon.entities.pixelmon.EntityPixelmon;
import com.pixelmonmod.pixelmon.enums.EnumSpecies;
import net.minecraft.server.v1_12_R1.BossBattle;
import net.minecraft.server.v1_12_R1.BossBattleServer;
import net.minecraft.server.v1_12_R1.ChatComponentText;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class SpawnListener implements Listener {
	
	private final PokeMsg plugin;
	Set<RangeDisplay> ce = new HashSet<>();
	
	public SpawnListener (PokeMsg plugin)
	{
		this.plugin = plugin;
		plugin.getPM().addPacketListener(this.getPacketAdapter(
				PacketType.Play.Server.REL_ENTITY_MOVE,
				PacketType.Play.Server.REL_ENTITY_MOVE_LOOK,
				PacketType.Play.Server.ENTITY_HEAD_ROTATION
				));
	}
	
	public  FileConfiguration getConfig()
	{
		return plugin.getConfig();
	}
	
	public PokeMsg getPlugin() {
		return plugin;
	}
	
	@EventHandler
	public void onPlayerMove(PlayerMoveEvent e) {
		Player p = e.getPlayer();
		//遍历指示器列表
		//神兽存在时更新显示
		if(ce == null) return;
		for (Iterator<RangeDisplay> iterator = ce.iterator(); iterator.hasNext(); ) {
			RangeDisplay c = iterator.next();
			if (c.getEntity() != null)
				c.update(p);
			else
				iterator.remove();
		}
	}


	@EventHandler
	public void onSuccessfulCapture(ForgeEvent event) {
		//指示器不为0且捕捉事件
		if(ce.size()>0 && event.getForgeEvent() instanceof SuccessfulCapture){
			SuccessfulCapture e = (SuccessfulCapture) event.getForgeEvent();
			if(EnumSpecies.legendaries.contains(e.getPokemon().getPokemonName())) {
				//遍历指示器列表
				for (Iterator<RangeDisplay> iterator = ce.iterator(); iterator.hasNext(); ) {
					RangeDisplay c = iterator.next();
					//指示器实体与捕捉实体相同
					if (c.getEntity() == null) {
						//在列表中移除
						iterator.remove();
						break;
					}
				}
			}
		}
	}


	@EventHandler
	public void onLegendarySpawn(ForgeEvent event) throws 
						IllegalArgumentException,
			SecurityException {
		//神兽刷新
		if ((event.getForgeEvent() instanceof LegendarySpawnEvent.DoSpawn) && getConfig().getBoolean("LegendarySpawn.enable"))
		{
			LegendarySpawnEvent.DoSpawn e = (DoSpawn) event.getForgeEvent();
			EntityPixelmon pokemon = e.action.getOrCreateEntity();
			//距离显示开启
			if(getConfig().getBoolean("LegendarySpawn.Common.bossbar")) {
				//创建显示器
				RangeDisplay rd = new RangeDisplay(
						pokemon,
						new BossBattleServer(new ChatComponentText(""),
											plugin.random(BossBattle.BarColor.class),
											BossBattle.BarStyle.NOTCHED_10),
						this);
				//显示器开启
				rd.showOrDelay();
				//添加到显示器列表
				ce.add(rd);
			}

			//神兽名字
			String pname = pokemon.getPokemonData().getDisplayName();
			//神兽坐标
		 	Location loc = new Location(e.action.spawnLocation.location.world.getWorld(), 
		 			e.action.spawnLocation.location.pos.func_177958_n(), 
		 			e.action.spawnLocation.location.pos.func_177956_o(), 
		 			e.action.spawnLocation.location.pos.func_177952_p());
		 	//地形名字
		 	String bname = plugin.biomeYml.getConfig().getString(
		 			loc.getWorld().getBiome((int)loc.getX(), (int)loc.getZ()).name()//标准英文地形名
		 			.toLowerCase()//转小写
		 			);
		 	//发生消息
			this.sendMsg(pname, bname, loc);
		}
	}
	

	public  void sendMsg(String pokeName, String biome, Location loc) {
		String world = loc.getWorld().getName();
		
		for (Player p:Bukkit.getOnlinePlayers())
		{
		//聊天框
		if (getConfig().getBoolean("LegendarySpawn.Common.chatbox"))
		{
			List<String> str = this.getConfig().getStringList("LegendarySpawn.message.chatbox.msg");
			for(String s:str)
			{
				
				p.sendMessage(this.bianLiang(
					s,
					pokeName,
					biome,
					""));
			}
			
			
		}
		//title标题
		if (getConfig().getBoolean("LegendarySpawn.Common.title"))
		{
			String title = getConfig().getString("LegendarySpawn.message.title.title");
			String subtitle = getConfig().getString("LegendarySpawn.message.title.subtitle");
			String lenmsg = "";
			int len = 0;
			
			//同世界距离计算
			if (p.getWorld().getName().equals(world))
			{
				len = getRange(
						p.getLocation().getX(), loc.getX(),
						p.getLocation().getZ(), loc.getZ());
				
				lenmsg = getConfig().getString("LegendarySpawn.message.title.lenmsg");
			}

			String length = lenmsg.equals("") ? "" : Integer.toString(len);
			title = this.bianLiang(title.replace("[lenmsg]", lenmsg),
					pokeName,
					biome,
					length);
			subtitle = this.bianLiang(subtitle.replace("[lenmsg]", lenmsg), 
					pokeName, 
					biome,
					length);
			p.sendTitle(title, subtitle, 
						getConfig().getInt("LegendarySpawn.message.title.fadeIn"),
						getConfig().getInt("LegendarySpawn.message.title.stay"),
						getConfig().getInt("LegendarySpawn.message.title.fadeOut"));
		}}
	}
	

	//神兽移动更新指示器
	public PacketAdapter getPacketAdapter(PacketType... pt) {
		return new PacketAdapter(PacketAdapter.params()
				.plugin(this.getPlugin())
				.serverSide()
				.gamePhase(GamePhase.PLAYING)
				.optionAsync()
				.options(ListenerOptions.SKIP_PLUGIN_VERIFIER)
				.types(pt)) {
			
			@Override  
			public void onPacketSending(PacketEvent event) {
				//获取神兽移动数据包
				PacketContainer packet = event.getPacket();
				//遍历指示器列表
				//UUID相同
				for (Iterator<RangeDisplay> iterator = ce.iterator(); iterator.hasNext(); ) {
					RangeDisplay c = iterator.next();
					if (c.getEntity() != null) {
						if (packet.getIntegers().getValues().get(0) ==
								c.getEntity().getBukkitEntity().getEntityId())
							//遍历神兽所在世界的玩家列表
							for (Player p : c.getEntity().getBukkitEntity().getWorld().getPlayers())
								//更新指示器
								c.update(p);
					} else
						iterator.remove();
				}
			}
			
		};
    }
	
	
	public int getRange(double x1, double x2, double z1, double z2) {
		return (int) Math.sqrt(
				(x1 - x2) * (x1 - x2)
				+
				(z1 - z2) * (z1 - z2)
				);
	}
	
	public String bianLiang(String str, String poke, String biome, String length) {
		
		if (str.contains("[pokemon]"))
    		str=str.replace("[pokemon]", poke);
		
		if (str.contains("[biome]"))
    		str=str.replace("[biome]", biome);
		
		if (str.contains("[length]"))
    		str=str.replace("[length]", length);
    	
		if (str.contains("&"))
    		str=str.replace("&", "§");
		
		return str;
		
	}
}